package net.csdn.business.gateway.component;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.jwt.BadJwtException;
import org.springframework.security.oauth2.jwt.JwtException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationDetails;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.security.oauth2.server.resource.InvalidBearerTokenException;
import org.springframework.util.StopWatch;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;

import java.util.Collection;

/**
 * @Auther: zhangyalei
 * @Date: 2022/12/5 19:34
 * @Description:
 */
@Slf4j
@RequiredArgsConstructor
public class CustomAuthenticationManagerAdapter implements ReactiveAuthenticationManager {

    private final ResourceServerTokenServices tokenServices;;


    @Override
    public Mono<Authentication> authenticate(Authentication authentication) {
        OAuth2Authentication auth=null;
        try {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start("authenticationManager.authenticate");
            if (authentication == null) {
                throw new InvalidTokenException("Invalid token (token not found)");
            }
            String token = (String) authentication.getPrincipal();
            auth = tokenServices.loadAuthentication(token);
            if (auth == null) {
                throw new InvalidTokenException("Invalid token: " + token);
            }
            //checkClientDetails(auth);
            /*if (authentication.getDetails() instanceof OAuth2AuthenticationDetails) {
                OAuth2AuthenticationDetails details = (OAuth2AuthenticationDetails) authentication.getDetails();
                // Guard against a cached copy of the same details
                if (!details.equals(auth.getDetails())) {
                    // Preserve the authentication details from the one loaded by token services
                    details.setDecodedDetails(auth.getDetails());
                }
            }*/
            //auth.setDetails(authentication.getDetails());
            auth.setAuthenticated(true);
            stopWatch.stop();
            log.info("当前任务名：{},耗时：{}ms",stopWatch.getLastTaskName(),stopWatch.getLastTaskTimeMillis());
        }catch (Exception exception){
            return Mono.error(exception);
        }
        return Mono.just(auth);

    }

}
